package com.security.config; // 安全配置类所在的包

import com.security.filter.JwtAuthenticationFilter; // JWT认证过滤器
import com.security.handler.CustomAccessDeniedHandler;
import com.security.service.InterceptAddressService;
import com.security.service.RequestLogService;

import org.springframework.context.annotation.Bean; // Spring Bean注解
import org.springframework.context.annotation.Configuration; // 配置类注解
import org.springframework.security.authentication.AuthenticationManager; // 认证管理器
import org.springframework.security.authentication.dao.DaoAuthenticationProvider; // DAO认证提供者
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; // 认证配置
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; // 启用方法级安全
import org.springframework.security.config.annotation.web.builders.HttpSecurity; // HTTP安全配置
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; // 启用Web安全
import org.springframework.security.config.http.SessionCreationPolicy; // 会话创建策略
import org.springframework.security.core.userdetails.UserDetailsService; // 用户详情服务
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; // BCrypt加密
import org.springframework.security.crypto.password.PasswordEncoder; // 密码编码器接口
import org.springframework.security.web.SecurityFilterChain; // 安全过滤器链
import org.springframework.security.web.access.expression.WebExpressionAuthorizationManager; // Web表达式授权管理器
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; // 用户名密码认证过滤器

@Configuration // 标记为配置类
@EnableWebSecurity // 启用Spring Security的Web安全支持
@EnableMethodSecurity // 启用方法级安全控制
public class SecurityConfig {

	private final UserDetailsService userDetailsService; // 用户详情服务
	private final JwtAuthenticationFilter jwtAuthenticationFilter; // JWT认证过滤器
	private final RequestLogService requestLogService; // 请求日志服务
	private final InterceptAddressService interceptAddressService; // 拦截地址服务

	// 构造器注入解决循环依赖
	public SecurityConfig(UserDetailsService userDetailsService, JwtAuthenticationFilter jwtAuthenticationFilter,
			RequestLogService requestLogService, InterceptAddressService interceptAddressService) {
		this.userDetailsService = userDetailsService;
		this.jwtAuthenticationFilter = jwtAuthenticationFilter;
		this.requestLogService = requestLogService;
		this.interceptAddressService = interceptAddressService;
	}

	@Bean // 定义密码编码器Bean
	public PasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder(); // 使用BCrypt强哈希加密
	}

	@Bean // 定义认证提供者Bean
	public DaoAuthenticationProvider authenticationProvider() {
		DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
		provider.setUserDetailsService(userDetailsService); // 设置用户详情服务
		provider.setPasswordEncoder(passwordEncoder()); // 设置密码编码器
		return provider;
	}

	@Bean // 定义认证管理器Bean
	public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
		return config.getAuthenticationManager(); // 从配置获取认证管理器
	}

	@Bean // 定义安全过滤器链
	public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
		http.csrf(csrf -> csrf.disable()) // 禁用CSRF保护(因使用JWT)
				.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 无状态会话
				).authorizeHttpRequests(auth -> {
					// 从配置的服务获取拦截规则 - 这些路径需要认证
					interceptAddressService.getInterceptUrls().forEach(url -> 
						auth.requestMatchers(url.getPattern()).authenticated()
					);
					
					// 默认允许所有请求（必须放在最后）
					auth.anyRequest().permitAll();
				})
				// 在用户名密码认证过滤器前添加JWT认证过滤器
				.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
				// 添加访问被拒处理器
				.exceptionHandling(
						exception -> exception.accessDeniedHandler(new CustomAccessDeniedHandler(requestLogService)));

		return http.build(); // 构建安全配置
	}
}